package com.example.Less.util;


import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.rmi.ServerException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@RequiredArgsConstructor
public class MinioUtil {

    private final MinioClient minioClient;
    private final ThumbnailUtil thumbnailUtil;

    private final String bucketName = "less";

    /**
     * 检查存储桶是否存在，不存在则创建
     */
    public void ensureBucketExists() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException,  InternalException, io.minio.errors.ServerException, XmlParserException {
        boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (!isExist) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            // 可以在这里设置存储桶的策略，例如设置为只读或公开
            log.info("Bucket '{}' created successfully.", bucketName);
        }
    }

    /**
     * 上传文件（MultipartFile格式，常用于接收前端上传）
     * @param file 前端上传的文件对象
     * @return 文件在MinIO中的存储对象名称（包含路径）
     */
    public String uploadFile(MultipartFile file) throws Exception {
        // 确保存储桶存在
        ensureBucketExists();

        // 生成一个唯一的对象名称，避免重名覆盖
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf(".")) : "";
        String objectName = UUID.randomUUID().toString() + fileExtension; // 你也可以添加路径，如 "images/"+UUID...

        // 上传文件
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(file.getInputStream(), file.getSize(), -1) // -1表示不分块
                        .contentType(file.getContentType())
                        .build()
        );

        log.info("File '{}' uploaded successfully as object '{}' in bucket '{}'.", originalFilename, objectName, bucketName);
        return objectName;
    }

    /**
     * 上传文件（通过本地文件路径）
     * @param filePath 本地文件绝对路径
     * @param objectName 在MinIO中存储的对象名称
     */
    public void uploadFile(String filePath, String objectName) throws Exception {
        ensureBucketExists();
        minioClient.uploadObject(
                UploadObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .filename(filePath)
                        .build()
        );
        log.info("Local file '{}' uploaded successfully as object '{}' in bucket '{}'.", filePath, objectName, bucketName);
    }

    /**
     * 获取文件的临时访问URL（预签名URL）
     * @param objectName 文件对象名称
     * @param expiry 有效期（单位：小时）
     * @return 临时可访问的URL
     */
    public String getFileUrl(String objectName, Integer expiry) throws Exception {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(objectName)
                        .expiry(expiry != null ? expiry : 7, TimeUnit.HOURS) // 默认7小时
                        .build()
        );
    }

    /**
     * 删除文件
     * @param objectName 文件对象名称
     */
    public void removeFile(String objectName) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build()
        );
        log.info("Object '{}' removed successfully from bucket '{}'.", objectName, bucketName);
    }

    /**
     * 上传缩略图到MinIO
     * @param thumbnailBytes 缩略图字节数组
     * @param objectName 对象名称
     * @param contentType 内容类型
     */
    public String uploadThumbnail(byte[] thumbnailBytes, String objectName, String contentType) throws Exception {
        ensureBucketExists();

        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(thumbnailBytes)) {
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(inputStream, thumbnailBytes.length, -1)
                    .contentType(contentType)
                    .build());
        }

        log.info("缩略图上传成功: {}", objectName);
        return objectName;
    }




}